package com.yq.cp.utils.wechat.handler;


import com.fasterxml.jackson.databind.JsonNode;
import com.yq.cp.config.MyException;
import com.yq.cp.utils.HttpUtil;
import com.yq.cp.utils.JsonUtil;
import com.yq.cp.utils.StringUtil;
import com.yq.cp.utils.wechat.configuration.MiniAppConfiguration;
import com.yq.cp.utils.wechat.model.SessionModel;
import com.yq.cp.utils.wechat.model.AccessTokenModel;
import com.yq.cp.utils.wechat.model.MiniAppLoginInfoModel;
import com.yq.cp.utils.wechat.model.MiniAppLoginModel;
import com.yq.cp.utils.wechat.utils.DecryptUtil;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Component;

@Log4j2
@Component
public class MiniAppHandler {

    private final static String MINIAPP_CODE2SESSION_URL = "https://api.weixin.qq.com/sns/jscode2session?appid=APPID&" +
            "secret=SECRET&js_code=JSCODE&grant_type=authorization_code";
    private final static String MINIAPP_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=" +
            "client_credential&appid=APPID&secret=APPSECRET";

    private final MiniAppConfiguration config;

    public MiniAppHandler(MiniAppConfiguration config) {
        this.config = config;
    }

    public SessionModel codeToSession(String code) {
        String url = MINIAPP_CODE2SESSION_URL
                .replace("APPID", config.getAppId())
                .replace("SECRET", config.getAppSecret())
                .replace("JSCODE", code);
        String body = HttpUtil.builder().doGet(url);
        log.info("Code to session -> {}", body);
        return JsonUtil.builder().fromJson(body, SessionModel.class);
    }

    public AccessTokenModel buildAccessToken() {
        String url = MINIAPP_ACCESS_TOKEN_URL
                .replace("APPID", config.getAppId())
                .replace("APPSECRET", config.getAppSecret());
        String body = HttpUtil.builder().doGet(url);
        log.info(body);
        return JsonUtil.builder().fromJson(body, AccessTokenModel.class);
    }

    public MiniAppLoginInfoModel buildLoginInfo(MiniAppLoginModel param) {
        log.info("Encode data -> {}", JsonUtil.builder().toJson(param));
        SessionModel model = this.codeToSession(param.getCode());
        if (StringUtil.isEmpty(model.getSessionKey())) {
            throw new MyException(model.getErrMsg());
        }
        MiniAppLoginInfoModel result = new MiniAppLoginInfoModel();
        result.setOpenId(model.getOpenId());
        String data = DecryptUtil.decrypt(param.getEncryptedData(), model.getSessionKey(), param.getIv());
        log.info("Decode data -> {}", data);
        if (StringUtil.isEmpty(data)) {
            throw new MyException("获取手机号失败");
        }
        JsonNode jn = JsonUtil.builder().parse(data);
        if (jn.has("phoneNumber")) {
            result.setMobile(jn.get("phoneNumber").asText());
            return result;
        }
        if (jn.has("phone_info")) {
            jn = jn.get("phone_info");
            result.setMobile(jn.get("phoneNumber").asText());
            return result;
        }
        return result;
    }

}
